﻿using Microsoft.EntityFrameworkCore;

namespace Devonline.AspNetCore;

/// <summary>
/// 重载的数据库上下文, 提供字符串类型主键的默认实现
/// 此基类上下文因为和身份上下文存在相同两个实体对象模型, 因此不可创建于统一数据库中
/// </summary>
public class BaseDbContext : BaseDbContext<Attachment, Comment, Credential, CredentialAdditional, DataIssue, Email, Feedback, IdCard, LimitList, Log, Message, Parameter, Personal, PersonalAdditional, Region, SensitiveWord, Todo, WhiteList, string>
{
    public BaseDbContext(DbContextOptions options) : base(options) { }
}

/// <summary>
/// 提供 TKey 作为主键类型的数据库上下文
/// 此基类上下文因为和身份上下文存在相同两个实体对象模型, 因此不可创建于统一数据库中
/// </summary>
/// <typeparam name="TKey"></typeparam>
public class BaseDbContext<TKey> : BaseDbContext<Attachment<TKey>, Comment<TKey>, Credential<TKey>, CredentialAdditional<TKey>, DataIssue<TKey>, Email<TKey>, Feedback<TKey>, IdCard<TKey>, LimitList<TKey>, Log<TKey>, Message<TKey>, Parameter<TKey>, Personal<TKey>, PersonalAdditional<TKey>, Region<TKey>, SensitiveWord<TKey>, Todo<TKey>, WhiteList<TKey>, TKey>
    where TKey : IEquatable<TKey>, IConvertible
{
    public BaseDbContext(DbContextOptions options) : base(options) { }
}

/// <summary>
/// 包含了基础数据对象模型的数据库上下文
/// 此基类上下文因为和身份上下文存在相同两个实体对象模型, 因此不可创建于统一数据库中
/// </summary>
/// <typeparam name="TAttachment"></typeparam>
/// <typeparam name="TComment"></typeparam>
/// <typeparam name="TCredential"></typeparam>
/// <typeparam name="TCredentialAdditional"></typeparam>
/// <typeparam name="TDataIssue"></typeparam>
/// <typeparam name="TEmail"></typeparam>
/// <typeparam name="TFeedback"></typeparam>
/// <typeparam name="TIdCard"></typeparam>
/// <typeparam name="TLimitList"></typeparam>
/// <typeparam name="TLog"></typeparam>
/// <typeparam name="TMessage"></typeparam>
/// <typeparam name="TParameter"></typeparam>
/// <typeparam name="TPersonal"></typeparam>
/// <typeparam name="TPersonalAdditional"></typeparam>
/// <typeparam name="TRegion"></typeparam>
/// <typeparam name="TSensitiveWord"></typeparam>
/// <typeparam name="TTodo"></typeparam>
/// <typeparam name="TWhiteList"></typeparam>
/// <typeparam name="TKey"></typeparam>
public class BaseDbContext<TAttachment, TComment, TCredential, TCredentialAdditional, TDataIssue, TEmail, TFeedback, TIdCard, TLimitList, TLog, TMessage, TParameter, TPersonal, TPersonalAdditional, TRegion, TSensitiveWord, TTodo, TWhiteList, TKey> : DbContext
    where TAttachment : Attachment<TKey>
    where TComment : Comment<TKey>
    where TCredential : Credential<TKey>
    where TCredentialAdditional : CredentialAdditional<TKey>
    where TDataIssue : DataIssue<TKey>
    where TEmail : Email<TKey>
    where TFeedback : Feedback<TKey>
    where TIdCard : IdCard<TKey>
    where TLimitList : LimitList<TKey>
    where TLog : Log<TKey>
    where TMessage : Message<TKey>
    where TParameter : Parameter<TKey>
    where TPersonal : Personal<TKey>
    where TPersonalAdditional : PersonalAdditional<TKey>
    where TRegion : Region<TKey>
    where TSensitiveWord : SensitiveWord<TKey>
    where TTodo : Todo<TKey>
    where TWhiteList : WhiteList<TKey>
    where TKey : IEquatable<TKey>, IConvertible
{
    public BaseDbContext(DbContextOptions options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<TCredential>(b =>
        {
            b.Property(x => x.State).HasDefaultValue(DataState.Available);
            b.Property(x => x.Type).HasDefaultValue(CredentialType.IdCard);
        });

        builder.Entity<TIdCard>(b =>
        {
            b.Property(x => x.State).HasDefaultValue(DataState.Available);
            b.Property(x => x.Gender).HasDefaultValue(Gender.Male);
        });

        builder.Entity<TLog>(b =>
        {
            b.Property(x => x.State).HasDefaultValue(DataState.Available);
            b.Property(x => x.Level).HasDefaultValue(LogLevel.Info);
        });

        builder.Entity<TPersonal>(b =>
        {
            b.Property(x => x.State).HasDefaultValue(DataState.Available);
            b.Property(x => x.Type).HasDefaultValue(AuthorizeType.Public);
            b.Property(x => x.Gender).HasDefaultValue(Gender.Male);
        });

        builder.Entity<TSensitiveWord>(b =>
        {
            b.Property(x => x.State).HasDefaultValue(DataState.Available);
            b.Property(x => x.Type).HasDefaultValue(SensitiveWordType.Political);
        });

        builder.Entity<TEmail>(b =>
        {
            b.Property(x => x.State).HasDefaultValue(DataState.Available);
            b.Property(x => x.IsHtml).HasDefaultValue(false);
        });

        builder.Entity<TAttachment>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TComment>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TCredentialAdditional>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TDataIssue>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TFeedback>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TLimitList>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TParameter>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TPersonalAdditional>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TRegion>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TTodo>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));
        builder.Entity<TWhiteList>(b => b.Property(x => x.State).HasDefaultValue(DataState.Available));

        builder.Entity<TMessage>(b => b.Property(x => x.Type).HasDefaultValue(MessageType.Text));
    }

    #region base entities
    public virtual DbSet<TAttachment>? Attachments { get; set; }
    public virtual DbSet<TComment>? Comments { get; set; }
    public virtual DbSet<TCredential>? Credentials { get; set; }
    public virtual DbSet<TCredentialAdditional>? CredentialAdditionals { get; set; }
    public virtual DbSet<TDataIssue>? DataIssues { get; set; }
    public virtual DbSet<TEmail>? Emails { get; set; }
    public virtual DbSet<TFeedback>? Feedbacks { get; set; }
    public virtual DbSet<TIdCard>? IdCards { get; set; }
    public virtual DbSet<TLimitList>? LimitLists { get; set; }
    public virtual DbSet<TLog>? Logs { get; set; }
    public virtual DbSet<TMessage>? Messages { get; set; }
    public virtual DbSet<TParameter>? Parameters { get; set; }
    public virtual DbSet<TPersonal>? Personals { get; set; }
    public virtual DbSet<TPersonalAdditional>? PersonalAdditionals { get; set; }
    public virtual DbSet<TRegion>? Regions { get; set; }
    public virtual DbSet<TSensitiveWord>? SensitiveWords { get; set; }
    public virtual DbSet<TTodo>? Todos { get; set; }
    public virtual DbSet<TWhiteList>? WhiteLists { get; set; }
    #endregion
}